#include "stdafx.h"
#include "CMessageRecvByEvent.h"

CMessageRecvByEvent::CMessageRecvByEvent(HANDLE callevent,HANDLE retevent,HANDLE mapobj)
{
	PVOID mapaddr=NULL;

	m_bIsClose=FALSE;
	m_sendevent=callevent;
	m_recvevent=retevent;
	m_mapobj=mapobj;
	try
	{
		if(mapobj)
		{
			if((mapaddr=::MapViewOfFile(m_mapobj,FILE_MAP_ALL_ACCESS, 0, 0,0))!=NULL)
			{
				m_stream= new strstream((char*)mapaddr,STACK_MAX_SIZE);
			}
		}
	}
	catch(...)
	{
		m_stream=NULL;
	}
}

CMessageRecvByEvent::~CMessageRecvByEvent()
{
	try
	{
		if((m_sendevent!=NULL)&&(m_stream!=NULL))
		{
			LONGLONG l=-1;
			m_stream->write((char*)&l,sizeof(LONGLONG));
			SetEvent(m_recvevent);
		}
		if(m_stream&&m_mapobj)
		{
			m_stream->seekg(0);
			UnmapViewOfFile(m_stream->str());
			delete m_stream;
			::CloseHandle(m_mapobj);
		}
		if(m_sendevent) ::CloseHandle(m_sendevent);
		if(m_recvevent)  ::CloseHandle(m_recvevent);
	}
	catch (...)
	{
	}
}

BOOL CMessageRecvByEvent::Open(PCHAR* names)
{
	PVOID mapaddr=NULL;
	try
	{
		if(names!=NULL)
		{
			if((m_sendevent=OpenEventA(EVENT_ALL_ACCESS,FALSE,names[0]))!=NULL)
			{
				if((m_recvevent=CreateEventA(NULL,FALSE,FALSE,names[1]))!=NULL)
				{
					if((m_mapobj=OpenFileMappingA(FILE_MAP_WRITE,FALSE,names[2]))!=NULL)
					{
						if(m_mapobj)
						{
							if((mapaddr=::MapViewOfFile(m_mapobj,FILE_MAP_ALL_ACCESS, 0, 0,0))!=NULL)
							{
								m_bIsClose=FALSE;
								m_stream= new strstream((char*)mapaddr,STACK_MAX_SIZE);
								return TRUE;
							}
						}
					}
					else
					{
						CloseHandle(m_sendevent);
						CloseHandle(m_recvevent);
					}
				}
				else
				{
					CloseHandle(m_sendevent);
				}
			}
		}
	}
	catch(...)
	{
	}
	return FALSE;
}

void CMessageRecvByEvent::Close()
{
	LONGLONG l=-1;
	try
	{
		m_stream->seekp(0);
		m_stream->write((char*)&l,sizeof(LONGLONG));
		m_bIsClose=TRUE;
		if(m_sendevent) SetEvent(m_sendevent);
	}
	catch(...)
	{
	}
}

UINT CMessageRecvByEvent::MessageRecv(IMessageTreament* treament)
{
	try
	{
		while(1)
		{
			WaitForSingleObject(m_sendevent, INFINITE);
			if(m_bIsClose==TRUE)
			{
				SetEvent(m_recvevent);
				break;
			}

			if(treament)
			{
				m_stream->seekg(sizeof(LONGLONG));
				m_stream->seekp(0);
				treament->Treament(m_stream);
			}
			SetEvent(m_recvevent);
		}
	}
	catch (...)
	{
		if((m_sendevent!=NULL)&&(m_stream!=NULL))
		{
			LONGLONG l=-1;
			m_stream->write((char*)&l,sizeof(LONGLONG));
			SetEvent(m_recvevent);
		}
	}
	return 0;
}